﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Web;

namespace Eksponent.CropUp.Plugins
{
    public class CleanUrls : Dialect, IHttpModule
    {
        public static Dialect BackingDialect = new ImageResizerDialect();
        public static string UrlPrefix = null;

        private static volatile bool _initialized = false;
        private static object _initLock = new object();

        void SetupCropUp()
        {
            if (!_initialized)
            {
                UrlPrefix = CropUp.Configuration.UrlPrefix;
                if (!UrlPrefix.EndsWith("/")) UrlPrefix += "/";
                if (UrlPrefix.StartsWith("/")) UrlPrefix = "~" + UrlPrefix;
                if (!UrlPrefix.StartsWith("~/")) UrlPrefix = "~/" + UrlPrefix;                

                lock( _initLock)
                {
                    if( !_initialized)
                    {
                        var cleanDialect = new CleanUrls();
                        CropUp.DialectResolver = () => cleanDialect;
                    }
                }
            }            
        }

        public void Init(HttpApplication context)
        {
            SetupCropUp();
            
            context.BeginRequest += (sender, args) =>
                {
                    var ctx = ((HttpApplication)sender).Context;

                    var path = VirtualPathUtility.ToAppRelative(ctx.Request.Path);
                    if( path.StartsWith(UrlPrefix, StringComparison.InvariantCultureIgnoreCase))
                    {
                        path = path.Substring(UrlPrefix.Length);
                        
                        var slash = path.IndexOf('/');
                        if( slash == -1)
                        {
                            throw new HttpException(404, "Invalid image url");
                        }
                        var imageArgsString = path.Substring(0, slash);
                        var imagePath = path.Substring(slash);
                        
                        var imageArgs = ImageSizeArguments.Parse(imageArgsString);

                        string queryString = context.Request.QueryString.ToString();
                        
                        ctx.RewritePath(BackingDialect.GetUrl(imagePath, imageArgs) + (!string.IsNullOrEmpty(queryString) ? "&" + queryString : null));
                    }
                };
        }

        public void Dispose()
        {
            
        }

        public override string GetUrl(string virtualPath, ImageSizeArguments arguments)
        {
            if( arguments == null ) arguments = new ImageSizeArguments();

            var sb = new StringBuilder(VirtualPathUtility.ToAbsolute(UrlPrefix));
            
            sb.Append(arguments.ToString());
            if (virtualPath.StartsWith("~")) virtualPath = virtualPath.Substring(1);
            sb.Append(virtualPath);
            return HttpUtility.UrlPathEncode(sb.ToString());
        }

        public override Size GetImageSize(string virtualPath)
        {
            return BackingDialect.GetImageSize(virtualPath);
        }

        private const int DimensionYouDontHaveX = 1049488485;
        private const int DimensionYouDontHaveY = 1079488485;
        public override string GetResponsiveUrl(string virtualPath, bool progressive, bool zoom)
        {
            var url = GetUrl(virtualPath, progressive
                ? new ImageSizeArguments { CropMode = CropUpMode.Responsive, Width = DimensionYouDontHaveX, Height = DimensionYouDontHaveY }
                : new ImageSizeArguments { CropMode = CropUpMode.BestFit, Width = DimensionYouDontHaveX, Height = DimensionYouDontHaveY, Zoom = zoom });

            return url.Replace(""+DimensionYouDontHaveX, "{w}").Replace(""+DimensionYouDontHaveY, "{h}");
        }

        public override void ClearCache(string virtualPath)
        {
            BackingDialect.ClearCache(virtualPath);
        }

        public override IDisposableBitmap GetBitmap(string virtualPath)
        {
            return BackingDialect.GetBitmap(virtualPath);
        }
    }
}
